.Programa
- Un programa es un archivo con instrucciones que no se ejecutan en ese momento.
- El programa es una entidad estatica, se le asignan los recurso al programa en ejecucion.

.Desarrollo de un programa
- La "Depuracion" sirve para encontrar errores en tiempo de ejecucion.
	(Buscar en Wikipedia los depuradores y sus 4 fases)

.Fases de desarrollo
- Biblioteca: conjunto de archivos orientados a una funcion. (Funciones matematicas, etc.)
	(Bibliotecas estaticas las referencias se asignan en el enlazado.) Saber como concepto
	(Bibliotecas dinamicas se asignan en la carga o ejecucion.) Saber como concepto
- Hasta el momento de ejecucion de un programa se manejan direcciones simbolicas no fisicas.

.Fases de desarrollo en UNIX
- "gcc" para compilar (gcc programa.c -o programa para darle el nombre "programa")
- "gdb" para depurar
- $ gdb "nombre ejecutable" (Sin comillas)
- Pasos del gcc:
	1º cpp -> Preprocesamiento
	2º comp -> Compilacion y optimizacion
	3º as -> Generacion de codigo objeto
	4º ld -> Enlace
- 1º fase: Coge directivas de los modulos, (Las que empiezan por '#' en el codigo), como "#include <stdio.h>".
Se ponen los "< >" cuando la libreria esta en la carpeta por defecto. Para coger el que yo quiera #include "asd.h" entre comillas.
Eso lo buscara en el directorio de trabajo y como segunda opcion en el directorio por defecto.

Para saber donde estan los archivos de cabecera de funciones como "printf" o "fork" hay que poner:
	man 3 printf
	man 2 fork
Con el numero especificas donde buscar el archivo dentro del man

- 2º fase: (gcc -E para parar en esta fase)

- 3º fase: (gcc -S para parar en esta fase) Es mas frecuente usarlo para saber que pasa a bajo nivel. (Ensamblador)

- 4º fase: (gcc -c para parar en esta fase)

- "-Wall" para sacar WARNINGS
	Ejemplo: gcc programa.c -Wall -o minishell
		(Esto compila el codigo en programa.c lo llama minishell y saca los WARNINGS)
- "-g" Si usamos el depurador despues debemos de meter el -g.
	(Introduce simbolos que necesita el depurador mas tarde)
- Si se para la compilacion en un punto luego se puede compilar desde ahi
	EJEMPLO: gcc programa.i -o minishell
- "-L" Buscar en el directorio que se indica
	EJEMPLO: gcc programa.c -Wall -L./ -ln  -o minishell
- Se pueden mezclar en una compilacion varios archivos compilados a medias, detenidos endistintas fases.
	EJEMPLO: gcc archivo1.i archivo2.o archivo3.s -o archivo

.Formato de un ejecutable
- Numero magico: Identificador que permite determinar si el archivo es ejecutable
- CP(Contador de programa) inicial
- Tabla de secciones: informacion para poder ejecutar el resto del ejecutable
- En un ejecutable NO almacenamos las variables locales, ya que estas se crean dinamicamente (sus direcciones), en la PILA.

.Proceso
	...

.PCB(Bloque de control de procesos)
- Es una estructura de informacion de procesos.
- Contine todo lo que tiene que saber el SO sobre los procesos.
- En Linux el PCB se llama "task_struct".
- Una de las cosas que se guarda en el PCB es la informacion de un proceso cuando se rompe con una interrupcion para retomarlo cuando termine la rutina de la interrupcion.

.Diagrama de estados de un proceso en Linux
- Ejecucion: (TASK_RUNNING) (El "listo" que aparece aqui no es el mismo que hemos visto antes)
- Parado:    (TASK_STOPPED) Esta asi cuando esta detenido por una señal(interrupcion software).
- Zombie:    (TASK_ZOMBI) Esta asi cuando, cuando ha finalizado, a devuelto todos los recursos, etc. PERO! no se ha eliminado su PCB. El proceso padre es el que se encarga de eliminar el PCB.
	Los procesos ZOMBI hay que evitar tenerlos porque solo ocupan memoria.
- Espera:    (TASK_UNINTERRUMPIBLE) Espera por un evento o recurso pero no despierta por ninguna señal.
- Listo:     (TASK_INTERRUMPIBLE) Espera por un recurso, etc.

.Espacio de direccionamiento virtual de un proceso
- El SO se encarga de dar la sensacion de que la RAM disponible es mayor. Consigue esto gracias a uso del disco duro.
- Se ejecuta en la memoria RAM solo lo necesario en cuanto a procesos en ese momento, en vez de ejecutar toda la aplicacion en la memoria.
- La MMU traduce direcciones virtuales a fisicas.

.Ejecutable y Mapa de memoria de un proceso
- La pila se asocia al proceso en ejecucion no al ejecutable.
- Heap reserva memoria dinamica. Es memoria que se reserva para los "new" en Java por ejemplo.
- Objeto de memoria es una region de memoria en unejecutable.
- La informacion sobre la memoria que se reserva se extrae del ejecutable. En concreto del objeto de memoria correspondiente.
- La pila no tiene soporte es decir no se crea a partir de algo del ejecutable, depende del sistema.
- Tamaño de las regiones: pueden tener tamaño variable como "heap" y la "pila" o tamaño fijo.
- Se pueden compartir regiones de codigo.
	Ejemplo: dos usuarios de linux usando "vi" a la vez, solo hay una copia del codigo.

.Mapa de memoria de un proceso en UNIX
- Se crea el mapa de memoria mediante fork() y exe().
- fork() crea el proceso.
- exe() ejecuta el proceso.
- Mapa de memoria NO es memoria fisica. Lo crea el SO y lo lleva a memoria segun estan siendo inciciado.
- Contexto de usuario, todas las estructuras axecibles por el usuario y el SO en modo usuario.
- Contexto del nucleo, todas las extructuras axecibles por el nucleo del SO en modo supervisor.
    					
					
				SMILEIS TIME!
		|  Contexto de usuario			Contexto nucleo    |
----------------|-----------------------------|----------------------------|
Modo supervisor |       :)                    |              :)            |
----------------|-----------------------------|----------------------------|
Modo usuario  	|	:)		      |		     D:            |
----------------|-----------------------------|----------------------------|

- En el contexto de nucleo se encuentran las PCB.

.Mapa de memoria de un proceso en Linux
- En "Sistema(1Gb)" se ecnuentras las PCB
- ESTO NO ES FISICO, EL MAPA DE MEMORIA ES VIRTUAL.

.Servicios POSIX para gestion de procesos
- El servicio POSIX para obtener el identificador de un proceso es getpid()

.Sincronizacion de la ejecucion de un proceso o hilo
- Habra conflicto de sincronizacion cuando los procesos son cooperantes, es decir, dependen unos de otros.
- Como los procesos dependen de otros, un proceso va a depender de la salida de otro.
	(Se habla de procesos pero pueden ser hilos)
- En las soluciones a estos conflictos esta "Productor-Consumidor": Hay un productor que crea informacion y un consumidor que modifica la informacion creada por el productor.
	El "pipe" es un ejemplo de esto. Si la tuberia esta llena el productor no puede dar informacion. Si la tuberia esta vacia el consumidor no puede consumir.
	Por lo que se debe producir antes de consumir.
- Cuando dos procesos o hilos quieren actualizar una misma variable (compartidda) se produce conflictos luego hay que tomar medidas.
- Condicion de carrera: Dos procesos quieren hacer "a++" (modificar la variable), a bajo nivel esto es: - load R0, a
													- add R0, 1
													- store a, R0
	Suponemos que el P1 carga la variable 'a' en R0, hay una interrupcion por el otro proceso, R0 de P1 es 1 (a=1).
	El P2 cumple su funcion sin interrupcion entonces carga 'a' en R0 le suma 1 y la guarda, por lo que a = 2.
	El P1 recupera la ejecucion con R0 = 1 ya cargado, le suma 1 y lo guarda en 'a' como a = 2.

	En este caso la salida no era la esperada (a = 3), por lo que necesitamos un sistema que detenga un proceso hasta que acabe otro.

.Mecanismo de sincronizacion con semaforos
- Solo pueden hacer tres funciones: Inicializacion, Operacion P y Operacion V.
- Operacion P:	Si el semaforo es positivo se decrementa en uno y continua.
	      	Si el semaforo esta a 0, el proceso se bloquea en una lista de espera.	

- Operacion V:	Si el semaforo no tiene procesos bloqueados se incremente una unidad.
		Si el semaforo tiene procesos bloqueados, despertara al primero que este en esa cola.

- Los mecanismos de sincronizacion deben de ser atomicos, el incremente y decremento del 'P' y 'V' se implementa con servicios atomicos en bajo nivel.

.Solucion consemaforos
(Seccion critica)
- P inicialmente esta a 1. Porque entra el primero pone P a 0 y el otro se encontrara P a 0 y quedara bloqueado.
- Hasta que el primero hace V suponiendo que P2 intenta entrar a la vez se bloquea y V lo desbloqueara.  Si no V pondra el semaforo a 1 para que el siguiente proceso tenga P a 1.

(Productor-Consumidor)
- S1 debara ser 0. Asi si el proceso consumidor intenta ejecutarse no podra porque sera P(0). Si el consumidor no intenta entrar durante la ejecucion V pondra S1 a 1 y podra entrar P mas tarde.

.Ejemplo 1
- El hijo es una clonacion del padre por lo que las 'a' son distintas. Si ponemos dos printf despues no  sabemos cual se ejecutara primero, solo sabemos que se ejecutara 3 y 4 o 4 y 3.

.Ejemplo 2
- Si el hijo se queda huerfano el init lo adopta y lo cierra por lo que nunca se quedaria zombi.

.Ejemplo 3
- Crea una estructura lineal O-O-O-O-O-O 

.Ejemplo 4
- Crea una estructura a lo ancho    |-O
				  O-|-O
				    |-O